/*
 * MySQL Cluster SNMP monitoring subagent
 * Copyright (C) 2011, Steven Ayre <steveayre@gmail.com>
 *
 * Version: MPL 1.1
 *
 * The contents of this file are subject to the Mozilla Public License Version
 * 1.1 (the "License"); you may not use this file except in compliance with
 * the License. You may obtain a copy of the License at
 * http://www.mozilla.org/MPL/
 *
 * Software distributed under the License is distributed on an "AS IS" basis,
 * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
 * for the specific language governing rights and limitations under the
 * License.
 *
 * The Original Code is MySQL Cluster SNMP monitoring subagent
 *
 * The Initial Developer of the Original Code is
 * Steven Ayre <steveayre@gmail.com>
 * Portions created by the Initial Developer are Copyright (C)
 * the Initial Developer. All Rights Reserved.
 *
 * Contributor(s):
 *
 * Steven Ayre <steveayre@gmail.com>
 *
 * config.h -- Configuration code
 *
 */

#include <stdlib.h>
#include <stdio.h>
#include <string.h>
#include <ctype.h>
#include <libdaemon/daemon.h>
#include "ndb_snmpd.h"
#include "common.h"
#include "config.h"

void ltrim(char *ptr)
{
	char *ptr2 = ptr;
	while(*ptr2 && isspace(*ptr2)) ptr2++;
	if (ptr2 != ptr) {
		memmove(ptr, ptr2, strlen(ptr)+1);
	}
}

void rtrim(char *ptr)
{
	char *ptr2 = ptr + strlen(ptr) - 1;

	while(ptr2 > ptr) {
		if (isspace(*ptr2)) {
			*ptr2 = '\0';
			ptr2--;
		}
		else {
			break;
		}
	}
}

int config_load(const char *filename)
{
	FILE *fp = NULL;
	char buffer[1024], section_name[1024], *name, *value;
	int status = 0, i;

	/* Initialise configuration */
	globals.num_clusters = 0;
	globals.clusters     = NULL;

	/* Open config file */
	if (!(fp = fopen(filename, "r"))) {
		daemon_perror(LOG_ERR, "fopen");
		status = -1;
		goto end;
	}

	/* Read configuration file lines */

	while(fgets(buffer, sizeof(buffer)-1, fp)) {
		char *ptr;

		/* Strip leading whitespace */
		ltrim(buffer);

		/* Ignore line if empty or starting with a comment */
		if (buffer[0] == '\0' || buffer[0] == '#') continue;

		/* Null-terminate at the linebreak */
		if ((ptr = strchr(buffer, '\r'))) *ptr = '\0';
		if ((ptr = strchr(buffer, '\n'))) *ptr = '\0';

		/* Strip trailing whitespace */
		rtrim(buffer);

		/* Start of a new section? */
		if (buffer[0] == '[') {
			ptr = buffer;
			while(*ptr) ptr++;
			ptr--;
			if (*ptr == ']') {
				/* Valid section header, copy name */
				*ptr = '\0';
				strncpy(section_name, buffer+1, sizeof(section_name));
				ltrim(section_name);
				rtrim(section_name);
				continue;
			}
		}

		/* Ignore line unless in the ndb_snmpd section */
		if (strcasecmp(section_name, "ndb_snmpd") != 0) continue;

		/* Find the =, extract the name-value pair */
		name  = buffer;
		value = NULL;
		if ((ptr = strchr(name, '='))) {
			*ptr = '\0';
			value = ptr + 1;
		}

		/* Strip whitespace from name-value */
		ltrim(name);
		rtrim(name);
		if (value) {
			ltrim(value);
			rtrim(value);
		}

		/* Store configuration */
		if (!strcasecmp(name, "ndb-connectstring")) {
			cluster_t *new_clusters;
			int idx;
			char *cluster_name, *connectstring;

			if (!(ptr = strchr(value, ':'))) {
				daemon_log(LOG_ERR, "Parse error");
				status = -1;
				goto end;
			}
			*ptr = '\0';
			ptr++;
			cluster_name  = name;
			connectstring = ptr;

			if (!(new_clusters = (cluster_t*)realloc(globals.clusters, sizeof(cluster_t)*(globals.num_clusters+1)))) {
				daemon_perror(LOG_ERR, "realloc");
				status = -1;
				goto end;
			}
			globals.clusters = new_clusters;
			idx = globals.num_clusters;
			globals.clusters[idx].info.idx = globals.num_clusters;
			if (!(globals.clusters[globals.num_clusters].info.name = strdup(cluster_name))) {
				daemon_perror(LOG_ERR, "strdup");
				status = -1;
				goto end;
			}
			if (!(globals.clusters[idx].info.connectstring = strdup(connectstring))) {
				daemon_perror(LOG_ERR, "strdup");
				status = -1;
				goto end;
			}
			globals.num_clusters++;
		}
	}

	/* Check for error while reading */
	if (ferror(fp)) {
		daemon_perror(LOG_ERR, "fgets");
		status = -1;
		goto end;
	}

	/* Display the loaded configuration */
	daemon_log(LOG_DEBUG, "=== Start of configuration ===");
	daemon_log(LOG_DEBUG, "# Clusters: %d", globals.num_clusters);
	for(i=0; i<globals.num_clusters; i++) {
		cluster_t *cluster = &globals.clusters[i];
		daemon_log(LOG_DEBUG, "Cluster %d: %s: NDB-ConnectString = '%s'", i+1, cluster->info.name, cluster->info.connectstring);
	}
	daemon_log(LOG_DEBUG, "=== End of configuration ===");

  end:
	/* Close file (if open) and return result */
	if (fp) fclose(fp);
	return status;
}

